home *** CD-ROM | disk | FTP | other *** search
- ' Camera demo
- '
- ' Demonstrates:
- ' Storing a camera position and direction in a matrix
- ' Moving the camera around (using a basic aeroplane like mechanism)
-
- ' Camera variables
- dim camera#(3)(3) ' Camera position and direction
- dim speed# ' Camera speed
-
- ' Working variables
- dim x, y, temp#(3), xaxis#, yaxis#
-
- ' Setup camera
- camera# = MatrixTranslate (0, 5, 0)
- speed# = 0.02
-
- TextMode (TEXT_OVERLAID)
- color (200, 200, 255)
- print "Use arrow keys to fly camera"
-
- ' Main loop
- while true
-
- ' Render frame
- glClear (GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER_BIT)
-
- ' Render from the camera's viewpoint
- ' Notes:
- ' * The camera stores the position and direction of the
- ' CAMERA relative to the WORLD.
- ' * We want to render the WORLD relative to the CAMERA,
- ' therefore we need to invert the matrix.
- ' * The camera is built from rotations and translations
- ' therefore we can use RTInvert to correctly invert
- ' it.
- glLoadMatrixf (RTInvert (camera#))
-
- ' Draw some quads
- for x = -10 to 10
- for y = -10 to 10
- glPushMatrix ()
- glTranslatef (x * 3, 0, y * 3)
- glBegin (GL_QUADS)
- glColor3f ( 1, 0, 0): glVertex2f ( 1, 3)
- glColor3f ( 0, 1, 0): glVertex2f (-1, 3)
- glColor3f ( 0, 0, 1): glVertex2f (-1, 0)
- glColor3f ( 1, 1, 1): glVertex2f ( 1, 0)
- glEnd ()
- glPopMatrix ()
- next
- next
- DrawText ()
- SwapBuffers ()
-
- ' Update the camera position
- while SyncTimer (10)
-
- ' Move the camera forward.
-
- ' We can do this by noticing that camera# is a rotation and translation matrix.
- ' Therefore if we split the matrix into columns, we know that the first three
- ' compose the basis axes of the rotation component.
- ' To put it in simpler terms:
- ' camera#(0) = The camera's LEFT vector
- ' camera#(1) = The camera's UP vector
- ' camera#(2) = The camera's BACKWARD vector
- ' We also know that the right hand column vector camera#(3) contains the
- ' camera's POSITION.
-
- ' Therefore to move the camera forward, we just need to add the camera's
- ' FORWARD vector (scaled by the current speed) to the camera's POSITION vector.
- ' (Note: We can get the camera's FORWARD vector by negating it's BACKWARD vector
- ' i.e by calculating -camera# (2))
- camera# (3) = camera# (3) + -camera# (2) * speed#
-
- ' Turn the camera
-
- ' We do this by multiplying the camera matrix by a rotation matrix.
- ' The rotation matrix is multiplied on the RIGHT HAND SIDE of the camera matrix.
- ' Therefore the rotation happens in CAMERA SPACE (i.e relative to the camera).
-
- ' If we rotate around the Z axis (points out of the screen) the camera will bank
- ' If we rotate around the X axis (points left) the camera will pitch.
-
- xaxis# = -Mouse_XD () * 30
- yaxis# = Mouse_YD () * 30
- if ScanKeyDown (VK_LEFT) then xaxis# = 1: endif
- if ScanKeyDown (VK_RIGHT) then xaxis# = -1: endif
- if ScanKeyDown (VK_UP) then yaxis# = -1: endif
- if ScanKeyDown (VK_DOWN) then yaxis# = 1: endif
- camera# = camera# * MatrixRotateZ (xaxis#) * MatrixRotateX (yaxis#)
-
- ' Turn the camera
- temp# = camera#(3)
- camera#(3) = vec4 (0, 0, 0, 1)
- camera# = MatrixRotateY (camera# (0)(1)) * camera#
- camera#(3) = temp#
-
- ' Orthonormalize the camera matrix.
-
- ' Everytime we multiply the matrix by a rotation, we introduce rounding error.
- ' This rounding error is insignificant for a reasonable number of transformations.
- ' However, as we are updating the camera 100 times per second the camera matrix
- ' will quickly become the result of 1000s of transformations, and eventually the
- ' rounding error can build up to the point where the matrix collapses or explodes.
-
- ' Orthonormalize performs a sequence of cross-products and vector normalizations
- ' to ensure the rotation component of the matrix is orthonormal, and minimize any
- ' accumulated rounding error.
- camera# = Orthonormalize (camera#)
- wend
- wend